/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.dataserializer.deserialize;

import com.inspur.edp.bef.spi.entity.AbstractBizEntityDeSerializer;
import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.cef.api.message.CefException;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.coreGenerator.base.serializer.dataser.deserializer.EntityDataDeserGenCtx;
import com.inspur.edp.cef.generator.overall.GeneratorUtil;
import com.inspur.edp.cef.spi.jsonser.util.SerializerUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.ThrowStatement;

public class GetChildDeserConvertorGenerator extends ClassMethodGenerator {

   private EntityDataDeserGenCtx deserContext;

   private String paramChildCode = "childCode";

   public GetChildDeserConvertorGenerator(EntityDataDeserGenCtx currentDataDeserContext) {
      this.deserContext = currentDataDeserContext;
   }

   @Override
   protected Block buildMethodBody() {
      Block block = ast.newBlock();
      buildIfStatements(block);
      buildThowExceptionStatement(block);
      return block;
   }

   private void buildThowExceptionStatement(Block block) {
      addImport(CefException.class.getTypeName());
      ThrowStatement throwStatement = GeneratorUtil.getThrowStatement(ast,null);
//      ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
//      classInstanceCreation.setType(new TypeInfo(RuntimeException.class).getType(ast));
//      throwStatement.setExpression(classInstanceCreation);
      block.statements().add(throwStatement);
   }

   private void buildIfStatements(Block block) {
      java.util.HashMap<String, MediateType> childObjects = deserContext.getChildSerTypes();
      if (childObjects == null || childObjects.size() == 0) {
         return;
      }
      for (Map.Entry<String, MediateType> childNode : childObjects.entrySet()) {
         IfStatement returnStatement = getIfStatement(childNode.getKey(), childNode.getValue());
         block.statements().add(returnStatement);
      }
   }

   private IfStatement getIfStatement(String key, MediateType objectType) {
      IfStatement ifStatement = ast.newIfStatement();
      setInfixExpression(key, ifStatement);
      setThenStatement(ifStatement, objectType);
      return ifStatement;
   }

   private void setThenStatement(IfStatement ifStatement, MediateType objectType) {
      Block block = ast.newBlock();
      ReturnStatement ifBodyReturnStatement = ast.newReturnStatement();
      ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
      classInstanceCreation.setType(ast.newSimpleType(ast.newName(objectType.getClassName())));
      ifBodyReturnStatement.setExpression(classInstanceCreation);
      block.statements().add(ifBodyReturnStatement);
      ifStatement.setThenStatement(block);
   }

   private void setInfixExpression(String key, IfStatement ifStatement) {
      MethodInvocation methodInvocation = ast.newMethodInvocation();
      methodInvocation.setName(ast.newSimpleName("isChildCodeEquals"));
      methodInvocation.arguments().add(ast.newSimpleName(paramChildCode));
      StringLiteral stringLiteral = ast.newStringLiteral();
      stringLiteral.setLiteralValue(key);
      methodInvocation.arguments().add(stringLiteral);
      methodInvocation.setExpression(GeneratorUtil.buildQualifiedName(ast, SerializerUtil.class));

      ifStatement.setExpression(methodInvocation);
   }

   @Override
   protected boolean getIsOverride() {
      return true;
   }

   @Override
   protected ArrayList<Modifier.ModifierKeyword> getAccessModifiers() {
      return new ArrayList<Modifier.ModifierKeyword>(Arrays
          .asList(new Modifier.ModifierKeyword[]{Modifier.ModifierKeyword.PROTECTED_KEYWORD}));
   }

   @Override
   protected String getMethodName() {
      return "getChildConvertor";
   }

   @Override
   protected ArrayList<ParameterInfo> getParameterCollection() {
      ParameterInfo parameterInfo = new ParameterInfo();
      parameterInfo.setParamName(paramChildCode);
      parameterInfo.setParamType(new TypeInfo(String.class));
      return new ArrayList<ParameterInfo>(Arrays.asList(new ParameterInfo[]{parameterInfo}));
   }

   @Override
   protected TypeInfo getReturnType() {
      return new TypeInfo(AbstractBizEntityDeSerializer.class);
   }
}
